#include "../include/muduo/net/TcpServer.h"
#include "../include/muduo/net/EventLoop.h"
#include "../include/muduo/net/TcpConnection.h"
#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>

class TranslateServer
{
    public:
        TranslateServer(int port)
            :_server(&_baseloop, muduo::net::InetAddress("0.0.0.0", port), 
            "TranslateServer", muduo::net::TcpServer::kReusePort)  // kReusePort 端口设置重启
        {
            // 使用bind绑定指定的回调函数用于避免this的传参
            _server.setConnectionCallback(std::bind(&TranslateServer::onConnection, this, std::placeholders::_1));
            _server.setMessageCallback(std::bind(&TranslateServer::onMessage, this, std::placeholders::_1,
                                    std::placeholders::_2, std::placeholders::_3));
        }

        void Start()
        {
            // 启动服务器
            _server.start(); // 进行事件监听，招客服务生
            _baseloop.loop(); // 进行事件循环阻塞，招待服务生
        }

        // 用于链接的回调函数，这个链接回调函数在新链接建立和链接关闭时调用
        void onConnection(const muduo::net::TcpConnectionPtr &conn)
        {
            if(conn->connected() == false)
            {
                std::cout << "新链接建立成功!\n" << std::endl;
            }
            else{
                std::cout << "新链接关闭成功!\n" << std::endl;
            }
        }

        std::string translate(const std::string &str)
        {
            static std::unordered_map<std::string, std::string> dict_map = {
                {"Hello", "你好"},
                {"hello", "你好"},
                {"你好", "hello"}
            };
            auto it = dict_map.find(str);
            if(it == dict_map.end())
            {
                return "None";
            }
            return it->second;
        }

        // 用于链接之后处理请求的回调函数
        void onMessage(const muduo::net::TcpConnectionPtr &conn, muduo::net::Buffer* buf, muduo::Timestamp)
        {
            // 通信链接收到请求后的回调函数
            // 1. 从buf获取Client的请求信息
            std::string str = buf->retrieveAllAsString();
            // 2. 调用translate接口进行处理
            std::string ret = translate(str);
            // 3. 将处理后的信息对客服端进行响应
            conn->send(ret);
        }
        
    private:
        // _baseloop是epoll的事件监控，会进行描述符的事件监控，触发事件后进行io操作
        muduo::net::EventLoop _baseloop;
        // server对象，主要用于设置回调函数，用于告诉服务器收到什么请求该如何进行处理
        muduo::net::TcpServer _server;
};

int main()
{
    TranslateServer server(8085);
    server.Start();
    return 0;
}